package com.starblink.android.basic.sensorsdata.spm

import com.starblink.android.basic.ext.toastUI
import com.starblink.android.basic.network.base.BaseApiClient
import com.starblink.android.basic.sensorsdata.room.entity.SKTraceEntity
import com.starblink.android.basic.sensorsdata.room.entity.SkAntEntity
import com.starblink.android.basic.sensorsdata.spm.cfg.SpmDefaultConfig
import com.starblink.android.basic.sensorsdata.spm.event.TrackEvent
import com.starblink.android.basic.sensorsdata.spm.impl.SPMStore
import com.starblink.android.basic.sensorsdata.spm.impl.fetchElementValue
import com.starblink.android.basic.sensorsdata.spm.impl.fetchPageValue
import com.starblink.android.basic.sensorsdata.spm.impl.fetchStatistics
import com.starblink.basic.util.ActivityStackManage
import com.starblink.basic.util.log.YYLogUtils
import java.util.Queue
import java.util.concurrent.LinkedTransferQueue

/**
 * 处理tracker 各种转换的辅助工具
 */
object GTrackerAssistUtils {

    var store = SPMStore()
    var previousEvent: String? = null


    var noDuplicationSet: HashSet<String> = hashSetOf()
    var totalNum = 0

    // 采集队列
    var collectQueue: LinkedTransferQueue<SkAntEntity> = LinkedTransferQueue()

    const val MAIN_URL = "main"
    var navigationUrl: String = MAIN_URL
    fun setup() {
        SpmDefaultConfig.getEnvValue()
    }

    fun fetchPageValue(name: Int): String {
        return store.fetchPageValue(name)
    }

    fun fetchElementValue(page: Int, element: Int): String {
        return store.fetchElementValue(page, element)
    }

    fun fetchStatisticsValue(page: Int, element: Int): String {
        return store.fetchStatistics(page, element)
    }

    fun fetchEventId(spmCnt: String): String {
        var spmArr = spmCnt.split(".")
        assert(spmArr.size == 5)
        return if (spmArr[3] != "0") {
            spmArr[3]
        } else if (spmArr[2] != "0") {
            spmArr[2]
        } else {
            "0"
        }
    }

    fun getPageId(spmCnt: String): String {
        var spmArr = spmCnt.split(".")
        assert(spmArr.size == 5)
        return if (spmArr[2] != "0") {
            spmArr[2]
        } else {
            "0"
        }
    }


    fun removeDuplication(ant: SkAntEntity, addSuccess: () -> Unit) {
        //针对元素曝光去重
        if (ant.event == TrackEvent.elementExposure.value) {
            if (ant.businessID != null) {
                if (noDuplicationSet.add(ant.businessID!!)) {
//                    YYLogUtils.e("spm---> 特殊业务类型 ${ant.businessID}")
                    addSetSuccess(ant)
                    addSuccess.invoke()
                } else {
//                    YYLogUtils.e("spm---> 重复曝光 已拦截 ${ant.businessID}")
                }
            } else if (noDuplicationSet.add(ant.trackUniqueId)) {
                addSetSuccess(ant)
                addSuccess.invoke()
            }
        } else {
            collectQueue.put(ant)
            addSuccess.invoke()
        }
    }

    private fun addSetSuccess(ant: SkAntEntity) {
        // 记录上次的行为事件
        collectQueue.put(ant)
        if (totalNum > 20000) {
            clearQueueSet()
        }
        totalNum++
    }

    private fun clearQueueSet() {
        totalNum = 0
        noDuplicationSet.clear()
        collectQueue.clear()
    }

    fun homePageClearQueueSet() {
        if (totalNum > 5000) {
            clearQueueSet()
        }
    }

    fun peekQueue(): SkAntEntity {
        return collectQueue.take()
    }

    fun removeId(id: String) {
        noDuplicationSet.remove(id)
    }

    /**
     *
     * add        增加一个元索                     如果队列已满，则抛出一个IIIegaISlabEepeplian异常
    　　remove   移除并返回队列头部的元素    如果队列为空，则抛出一个NoSuchElementException异常
    　　element  返回队列头部的元素             如果队列为空，则抛出一个NoSuchElementException异常
    　　offer       添加一个元素并返回true       如果队列已满，则返回false
    　　poll         移除并返问队列头部的元素    如果队列为空，则返回null
    　　peek       返回队列头部的元素             如果队列为空，则返回null
    　　put         添加一个元素                      如果队列满，则阻塞
    　　take        移除并返回队列头部的元素     如果队列为空，则阻塞
    drainTo(list)   一次性取出队列所有元素
    https://blog.csdn.net/qq_27184497/article/details/116093422
     */

    /**
     * 在不好拿page的地方 更加当前route的path 获取page
     */
    fun getCurrentPageRoute(): String {
        var pageName = "0"
        when (navigationUrl) {
            MAIN_URL -> "0"

        }
        if (pageName == "0") {
            if (!BaseApiClient.isPub()) {
                toastUI("pageName 为 0，请检查")
            }
        }
        return pageName
    }
}